#!/usr/bin/python3
# -*- coding: utf-8 -*-

print("Running")

print("--------------1.基本数据类型------------------")
# - Number（数字）
# - String（字符串）
# - bool（布尔类型）(py中 bool是int的子类型，可以进行相加运算)
# - List（列表）
# - Tuple（元组）
# - Set（集合）
# - Dictionary（字典）

t1 = 12
t2 ="12" # python不区分单引号还是双引号
t3 = True
t4 = [1,2]# 列表用[]
t5 = (1,2,3) # 元组用()
t6 = {1,2,3} # Set用{}
t7 = {'n':1,'o':2}# 字典用{},需要有key、value

print("---------------2.1列表for遍历-----------------")

array=[1,2,3]

# 遍历

for index,value in enumerate(array):
    print("{index} = {value}".format(index=index,value=value))

print("---------------2.2列表迭代器-----------------")

# 使用迭代器
array_iterator = iter(array)

while True:
    try:
        print(next(array_iterator))
    # 使用此异常，标识遍历结束
    except StopIteration:
        print("finished")
        break

print("-------------2.3列表生成器-------------------")

# 使用生成器
def f(list):
    for item in list:
        if(item==2):
            yield item
        print("item: " + str(item))
print(next(f(array)))

print("-------------3推导式-------------------")

# 推导式 简化的运算代码。 列表 [] 包裹，元组 () 包裹且返回是个生成器

array2 = [1,2,3,4,5,6,7,8,9]
# 筛选偶数

filterArray = [value for value in array2 if value % 2 == 0] # value必须是已经声明的变量
print(filterArray)
for value in filterArray:
    print ("filter: "+str(value))

print("-------------4函数-------------------")
def fun1(str):
    print(str)
fun1("hello world")

print("-------------4.1不定长参数-------------------")
# 单 * ，元组方式传入
def fun2(str,*args):
    print(args)
fun2("1",1,2,3)
fun2("1-1",[1,2,3,4,5])# 这个[1,2,3,4,5]只会当成一个列表元素参数

# 双 * ，字典方式传入
def fun3(str,**args):
    print(args)
fun3("2",a=1,b=2,c=3)

# 单 * ，独自出现。（称为关键字形参）后面必须指定关键字。类似kotlin中的命名参数
def fun3(str,*,c,d):
    print(c)
    print(d)
fun3("3",c="hello",d="123")# 指定名字

print("-------------4.2匿名函数-------------------")
# 关键字 lambda 修饰。`lambda [arg1 [,arg2,.....argn]]:expression`
fun4 = lambda x : x + 10 # 这个函数意思是 传入x参数，表达式是 x+10，返回是表达式的运算值
print(fun4(2))

print("-------------4.3强制位置参数-------------------")
# / 表示强制位置参数，后面的参数可以使用位置形参也可以使用命名参数。但不使用命名参数时必须保证位置正确
def fun5(a,b,/,c,d,*,e,f):
    print(a,b,c,d,e,f)

fun5(1,2,d=1,c=2,e=3,f=4) # 正确，c、d 使用命名参数，可忽略位置
# fun5(1,2,d=1,2,e=3,f=4)# 错误，c没有使用命名参数，必须保证位置正确

print("-------------5装饰器-------------------")

# 格式：@装饰器名 return 方法
def decoratorFunc(original_function):
    def wrapperFunction(a,b):
        print("before original_function invoke")
        # 调用原始函数
        print("result: "+original_function(a, b))
        print("after original_function invoke")
    return wrapperFunction

@decoratorFunc
def myFunc(a,b):
    return "a = {},b = {}".format(a,b)

myFunc(1,2)

print("-------------6.1错误和异常-------------------")

# try...except..finally 捕获
try:
    try:
        a = 10 / 0
    except ZeroDivisionError:
        print("收到了一个ZeroDivisionError")
        raise ValueError("值错误")#继续抛出异常
    except NameError:
        print("收到了一个NameError")
    else:#当没有异常时执行
        print("未出现异常")
    finally:
        print("流程结束")
except ValueError:
    print("收到了一个ValueError")


print("-------------6.2自定义错误-------------------")
class CustomError(Exception):#CustomError(Exception) 表示单继承
    pass

try:
    raise CustomError("1123")
except CustomError as e:
    print(e)

print("-------------7上下文-------------------")

# 使用with 管理资源，多用于打开file文件
# with 修饰的对象必须实现 始、末 两个函数，open就实现了，可以保证在结束时自动调用close方法以关闭文件。
with open('file.txt',mode='r',encoding='utf-8') as f:
    for line in f:
        print(line)

print("-------------8.1面向对象-定义类-------------------")

class A:
    def __init__(self,name):#这是构造函数
        self.name = name
a = A("A")
print(a.name)
print("-------------8.2继承-------------------")

#单继承 
class TestClass(A):
    pass
testClass = TestClass("A")
print(testClass.name)
#多继承
class B:
    def __init__(self,age):
        self.age = age

b = B("B")
print(b.age)

class TestClass2(A,B):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
testClass2 = TestClass2("A","B")
print(testClass2.name)
print(testClass2.age)
